package com.dxl.web.account.tool;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.dxl.common.annotation.RequirePermission;
import com.dxl.common.spring.AppCtxHolder;
import com.dxl.common.utils.BeanUtils;
import com.dxl.common.utils.MD5;
import com.dxl.common.utils.Utils;
import com.dxl.entity.account.Account;
import com.dxl.entity.account.AccountRole;
import com.dxl.entity.account.Function;
import com.dxl.entity.account.Role;
import com.dxl.entity.account.RoleFunction;
import com.dxl.service.common.BaseService;

public class AccountSetup {
	private static final Logger LOG = Logger.getLogger(AccountSetup.class);
	
	public static final AccountSetup ME = new AccountSetup();
	
	private AccountSetup(){}
	
	
	public void setup() throws Exception{
		BaseService service = AppCtxHolder.getBean("baseService");
		service.del(Account.class);
		service.del(AccountRole.class);
		service.del(Role.class);
		service.del(RoleFunction.class);
		service.del(Function.class);
		
		setupFunctions();
		setupRole();
		setupAccount();
	}
	
	public Account setupAccount() {
		Account account = new Account();
		account.setAccount("admin");
		account.setName("管理员");
		account.setEmail("dengxiaolin@kuyumall.com");
		account.setMobile("15102049689");
		account.setPassword(MD5.crypt("admin"));
		
		BaseService service = AppCtxHolder.getBean("baseService");
		
		service.save(account);
		List<Role> roleList = service.list(Role.class);
		AccountRole accountRole;
		for (Role role : roleList) {
			accountRole = new AccountRole();
			accountRole.setAccountId(account.getId());
			accountRole.setRoleId(role.getId());
			service.save(accountRole);
		}
		return account;
	}
	
	public void setupRole() {
		BaseService service = AppCtxHolder.getBean("baseService");
		
		Role role = new Role();
		role.setName("所有角色");
		role.setDescription("所有角色");
		service.save(role);
		
		String pid = role.getId();
		role = new Role();
		role.setName("超级管理员");
		role.setDescription("超级管理员");
		role.setParentId(pid);
		service.save(role);
		
		List<Function> functions = service.list(Function.class);
		RoleFunction roleFunction;
		for (Function function : functions) {
			roleFunction = new RoleFunction();
			roleFunction.setRoleId(role.getId());
			roleFunction.setFunctionId(function.getId());
			service.save(roleFunction);
		}
	}

	@SuppressWarnings("rawtypes")
	public void setupFunctions() {
		BaseService service = AppCtxHolder.getBean("baseService");
		List<Class> cs = new ArrayList<Class>();
		String[] beanDefinitionNames = AppCtxHolder.getAppCtx().getBeanDefinitionNames();
		for (String beanDefinitionName : beanDefinitionNames) {
			if (beanDefinitionName.endsWith("Controller")) {
				cs.add(AppCtxHolder.getBean(beanDefinitionName).getClass());
			}
		}
		
//		ResourcePatternResolver rpr = new PathMatchingResourcePatternResolver();
//		Resource[] res;
//		try {
//			res = rpr.getResources("classpath*: com/dxl/web/account/controller/*.class");
//		} catch (IOException e) {
//			LOG.error(e.getMessage(), e);
//			return;
//		} 
//		String path;
//		Class<?> clazz;
//		for (Resource re : res) {
//			try {
//				path = re.getURL().getPath();
//				path = path.substring(path.indexOf("/com/") + 1, path.lastIndexOf(".")).replace("/", ".");
//				clazz = Class.forName(path);
//				cs.add(clazz);
//			} catch (Exception e) {
//				LOG.error(e.getMessage(), e);
//			}
//		}
		
		Function root = new Function();
		root.setCode("ROOT");
		root.setName("所有功能");
		root.setDescription("所有功能");
		service.save(root);
		
		Set<String> cache = new HashSet<String>();
		Function parent = null, function;
		RequirePermission cAn, an;
		String code;
		for (Class c : cs) {
			try {
				cAn = (RequirePermission) BeanUtils.getClassAnnotation(c, RequirePermission.class);
			} catch (Exception e) {
				LOG.error(e.getMessage(), e);
				continue;
			}
			if (Utils.isNotNull(cAn) && Utils.isNotEmpty(cAn.value())) {
				code = cAn.value()[0];
				if (cache.add(code)) {
					parent = new Function();
					parent.setCode(code);
					parent.setName(Utils.isBlank(cAn.name()) ? code : cAn.name());
					parent.setDescription(Utils.isBlank(cAn.desc()) ? cAn.name() : cAn.desc());
					parent.setParentId(root.getId());
					service.save(parent);
				}
			}
			
			Method[] ms = c.getDeclaredMethods();
			for (Method m : ms) {
				try {
					an = (RequirePermission) m.getAnnotation(RequirePermission.class);
				} catch (Exception e) {
					LOG.error(e.getMessage(), e);
					continue;
				}
				if (Utils.isNotNull(an) && Utils.isNotEmpty(an.value())) {
					for (String value : an.value()) {
						if (cache.add(value)) {
							function = new Function();
							function.setCode(value);
							function.setName(Utils.isBlank(an.name()) ? value : an.name());
							function.setDescription(Utils.isBlank(an.desc()) ? an.name() : an.desc());
							function.setParentId(parent.getId());
							service.save(function);
						}
					}
				}
			}
		}
	}
}
